﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Treely.Data.Model;
using Treely.Data.Model.Abstract;

namespace TreelyConsole
{
    internal class Program
    {
        private static Random RandomNumber = new Random();

        private static void Main(string[] args)
        {
            /*Console.WriteLine("Enter \"student\" to take a quiz, or \"parent\" to create and edit quizzes.");
            string response = string.Empty;
            while (response.ToLower() != "student" && response.ToLower() != "parent")
            {
                response = Console.ReadLine();
            }
            if (response.ToLower() == "student")*/
            TakeQuiz();
            //            if (response.ToLower() == "parent")
            //            {
            //                var admin = new AdminConsole();
            //            }
        }

        private static void TakeQuiz()
        {
            Console.ForegroundColor = ConsoleColor.White;
            int CorrectAnswers = 0;

            DifficultyLevel level = DifficultyLevel.SecondGrade;

            var stopWatch = new Stopwatch();

            var quiz = QuizFactory.MakeDefaultQuestions(level, 40);
            IAnswerable question;
            ColorWriter(string.Format("Starting quiz for {0} : {1} questions total...", level, quiz.Count), ConsoleColor.Yellow);
            Console.WriteLine("Press <ENTER> when ready.");
            Console.ReadLine();
            Console.WriteLine();
            for (var i = 0; i < quiz.Count; i++)
            {
                stopWatch.Reset();
                CountdownToNextQuestion(5);
                question = quiz[i];
                Console.WriteLine("#{0} out of {1}", i + 1, quiz.Count);
                Console.WriteLine(question.Body);
                ColorWriter(question.ToStringVertical(), ConsoleColor.White);
                question.Started = DateTime.Now;
                bool? result = null;
                while (result == null)
                {
                    var answer = Console.ReadLine();
                    result = question.IsCorrect(answer);
                    CorrectAnswers += OnAnswer(result, question);
                }
                question.Finished = DateTime.Now;
                // Console.WriteLine("It took you {0} seconds.", stopWatch.Elapsed.TotalSeconds.ToString("####"));
                Console.WriteLine();
            }

            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine();
            var timeElapsed = quiz.Select(x => x.TimeUsed).Aggregate((x, y) => x + y);

            Console.WriteLine("You got {0} out of {1} questions right!", CorrectAnswers, quiz.Count);
            Console.WriteLine("This quiz took you {0} minutes and {1} seconds.", timeElapsed.Value.Minutes, timeElapsed.Value.Seconds);
            Summary(quiz);
            Console.WriteLine("<Type \"quit\" to exit>");
            string exitPrompt = string.Empty;
            while (!exitPrompt.Equals("quit", StringComparison.OrdinalIgnoreCase))
            {
                exitPrompt = Console.ReadLine();
            }
        }

        private static void Summary(List<IAnswerable> questions)
        {
            try
            {
                var questionTypes = questions.Select(x => x.Subject).Distinct().ToList();
                questionTypes.ForEach(x =>
                {
                    Console.WriteLine("{0} : You got {1} out of {2} questions right, with an average of {3} seconds.",
                        questions.Where(y => y.Subject == x).First().Subject,
                        questions.Where(y => y.Subject == x && y.Correct.GetValueOrDefault()).Select(y => 1).Sum(),
                        questions.Where(y => y.Subject == x).Select(y => 1).Sum(),
                        Math.Round(questions.Where(y => y.Subject == x).Select(y => y.TimeUsed.GetValueOrDefault().TotalSeconds).Average(), 2)
                        );
                });
            }
            catch
            {
            }
        }

        /// <summary>
        /// Returns correct points;
        /// </summary>
        /// <param name="result"></param>
        /// <param name="question"></param>
        /// <returns></returns>
        private static int OnAnswer(bool? result, IAnswerable question)
        {
            switch (result)
            {
                case true:
                    ColorWriter("CORRECT!", ConsoleColor.Green);
                    question.Correct = true;
                    return 1;

                case false:
                    ColorWriter(string.Format("INCORRECT. The correct answer was: {0}", question.CorrectAnswer), ConsoleColor.Red);
                    question.Correct = false;
                    break;

                default:
                    ColorWriter("You did not enter a valid number. Try again.", ConsoleColor.Yellow);
                    break;
            }
            return 0;
        }

        private static void ColorWriter(string text, ConsoleColor color, bool newLine = true)
        {
            Console.ForegroundColor = color;
            if (newLine) Console.WriteLine(text);
            else Console.Write(text);
            Console.ForegroundColor = GetConsoleColor();
        }

        private static void CountdownToNextQuestion(int seconds)
        {
            Console.Write("Next question in ");

            for (var i = seconds; i > 0; i--)
            {
                ColorWriter(string.Format("{0}", i), GetConsoleColor(i), false);
                Thread.Sleep(250);
                ColorWriter(".", GetConsoleColor(i), false);
                Thread.Sleep(250);
                ColorWriter(".", GetConsoleColor(i), false);
                Thread.Sleep(250);
                ColorWriter(".", GetConsoleColor(i), false);
                Thread.Sleep(250);
            }
            ColorWriter("GO!", ConsoleColor.White);
            Thread.Sleep(50);
            Console.Clear();
        }

        private static ConsoleColor GetConsoleColor(int urgency = 0)
        {
            switch (urgency)
            {
                case 5:
                    return ConsoleColor.DarkRed;

                case 4:
                    return ConsoleColor.Red;

                case 3:
                    return ConsoleColor.DarkYellow;

                case 2:
                    return ConsoleColor.DarkGreen;

                case 1:
                    return ConsoleColor.Green;

                default:
                    return ConsoleColor.Gray;
            }
        }
    }
}